#include "cmd.h"
#include "const.h"
#include "utils.h"

bool checkCommand(cmd command)
{
    if(command.command.empty())
        return false;

    else if(command.line.empty())
        return false;

    else if(command.params.empty())
        return false;

    else if(command.type == UNKNOWN)
        return false;

    else
        return true;
}

cmd *createCommand(std::string codeline)
{
    cmd *c = new cmd;
    c->line = io()->stripN(codeline.substr(0, codeline.find("\n")));

    if(codeline.find(" ") == FIND_ERROR_CODE) // s'il n'y a pas d'espaces
    {
        c->params = ""; // c'est qu'il n'y a pas de parametres
        c->command = io()->stripN(c->line);
    }
    else
    {
        lexResult lr = io()->lex(c->line, " ", 2);
        c->command = lr.result[0];
        c->params = lr.result[1];
    }


    io()->dbgMsg("codeline = ", c->line);
    io()->dbgMsg("command = ", c->command);
    io()->dbgMsg("params = ", c->params);


    if(c->command == "alloc")
        c->type = ALLOC;
    else if(c->command == "assign")
        c->type = ASSIGN;
    else if(c->command == "exit")
        c->type = EXIT;
    else if(c->command == "clear")
        c->type = CLEAR;
    else if(c->command == "help")
        c->type = HELP;
	else if(c->command == "vlist")
		c->type = VLIST;
	else if(c->command == "clist")
		c->type = CLIST;
	else if(c->command == "print")
		c->type = PRINT;
	else if(c->command == "function")
		c->type = FUNCTION;
	else if(c->command == "new")
		c->type = NEW;
	else if(c->command == "call")
		c->type = CALL;
	else if(c->command == "scan")
		c->type = SCAN;
	else if(c->command == "input")
		c->type = INPUT;
    else
        c->type = UNKNOWN;

    return c;
}

void cmdProc(std::string codeline, std::map<std::string,Variable*> *v)
{
    cmd *com = createCommand(codeline);

    switch(com->type)
    {
		// exec Calls
        case ALLOC:
            execAlloc(*com, v);
            break;
        case ASSIGN:
            execAssign(*com, v);
            break;
		case VLIST:
			execVList(*com, v);
			break;
		//Insta-calls
		case EXIT:
			v->clear();
			delete com;
			delete v;
            exit(0);
            break;
        case CLEAR:
            system("cls");
            break;
        case HELP:
            std::cout << "Quick help:\n~~: user input field\n";
                io()->dbgMsg("debugging information\n", "");
            std::cout << "~~# interpreter output\n\n";
            break;
		// More exec calls
		case PRINT:
			execPrint(*com, v);
			break;
		case INPUT:
			execInput(*com, v);
			break;
		case NEW:
			execNew(*com, v);
			break;
		case CALL:
			execCall(*com, v);
			break;
		case SCAN:
			execScan(*com, v);
			break;
		/* a la place d'utiliser ces commandes, on devrait utiliser evalMathExp() non?*/
		case ADD:
			return; // not implemented
			break;
		case SUB:
			return; // not implemented
			break;
		case MUL:
			return; // not implemented
			break;
		case DIV:
			return; // not implemented
			break;
        default:
            std::cout << "cmdProc Error(C0): Unknown command" << std::endl;
			io()->hlpMsg("Did you correctly type the command?");
            break;
    }
}
